/**
*****************************************************************************************
*     Copyright(c) 2017, Realtek Semiconductor Corporation. All rights reserved.
*****************************************************************************************
  * @file     bls.h
  * @brief    Head file for using blood pressure service.
  * @details  BLS data structs and external functions declaration.
  * @author
  * @date
  * @version  v1.0
  * *************************************************************************************
  */

/* Define to prevent recursive inclusion */
#ifndef _BLS_H_
#define _BLS_H_

#ifdef  __cplusplus
extern "C" {
#endif      /* __cplusplus */

/* Add Includes here */
#include "profile_server.h"
#include "bls_define.h"

/** @defgroup Blood Pressure Service
  * @brief  Blood Pressure Service
   * @details

     The Blood Pressure Service exposes blood pressure and other data related to a noninvasive blood pressure monitor
     for consumer and professional healthcare applications.

     Blood Pressure Service generally makes up a profile with some other services, and it can provide the state of blood pressure.

     The default supported feature provided by BLS is the indicate property of blood pressure measurement characteristic,
     the read property of blood pressure feature characteristic, and the application developers can modify the feature supported
     by BLS according to their own requirements.
     The specific configuration process can be achieved by modifying file @ref bls_define.h.

    * <b>Example usage</b>
    * \code{.c}

         #define BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT    1

    * \endcode

     Application shall register blood pressure service when initialization through @ref bls_add_service function.

     Application can set the blood pressure feature of BLS through @ref bls_set_parameter function.

     Application can send the blood pressure measurement value of BLS to the client with a indication through @ref bls_blood_pressure_measurement_value_indicate function.

     Application can send the intermediate cuff pressure value of BLS to the client with a notification through @ref bls_intermediate_cuff_pressure_value_notify function.

  * @{
  */

/*============================================================================*
 *                         Macros
 *
 *============================================================================*/
/** @defgroup BLS_Exported_Macros BLS Exported Macros
  * @brief
  * @{
  */
#define  BLS_INDICATE_BLOOD_PRESSURE_MEASUREMENT_ENABLE   1
#define  BLS_INDICATE_BLOOD_PRESSURE_MEASUREMENT_DISABLE 2
#define  BLS_NOTIFY_INTERMEDIATE_CUFF_PRESSURE_ENABLE 3
#define  BLS_NOTIFY_INTERMEDIATE_CUFF_PRESSURE_DISABLE 4

/** End of BLS_Exported_Macros
* @}
*/

/*============================================================================*
 *                         Types
 *============================================================================*/
/** @defgroup BLS_Exported_Types BLS Exported Types
  * @brief
  * @{
  */

/**
*  @brief Blood pressure service parameter type
*/
typedef enum
{
    BLS_PARAM_BLOOD_PRESUREE_FEATURE
} T_BLS_PARAM_TYPE;

typedef union
{
    uint8_t notification_indification_index;
} T_BLS_UPSTREAM_MSG_DATA;

/**
*  @brief set blood pressure parameter upstream callback data
*/
typedef struct
{
    uint8_t                 conn_id;
    T_SERVICE_CALLBACK_TYPE msg_type;
    T_BLS_UPSTREAM_MSG_DATA msg_data;
} T_BLS_CALLBACK_DATA;

/** End of BLS_Exported_Types
* @}
*/


/*============================================================================*
 *                         Functions
 *============================================================================*/
/** @defgroup BLS_Exported_Functions BLS Exported Functions
  * @brief
  * @{
  */

/**
  * @brief       Add blood pressure service to the BLE stack database.
  *
  *
  * @param[in]   p_func  Callback when service attribute was read, write or cccd update.
  * @return Service id generated by the BLE stack: @ref T_SERVER_ID.
  * @retval 0xFF Operation failure.
  * @retval Others Service id assigned by stack.
  *
  * <b>Example usage</b>
  * \code{.c}
     void profile_init()
     {
         server_init(1);
         bls_id = bls_add_service(app_handle_profile_message);
     }
  * \endcode
  */
T_SERVER_ID bls_add_service(void *p_func);

/**
 * @brief       Set a blood pressure service parameter.
 *
 *              NOTE: You can call this function with a blood pressure service parameter type and it will set the
 *                      blood pressure service parameter.  Blood pressure service parameters are defined in @ref T_BLS_PARAM_TYPE.
 *                      If the "len" field sets to the size of a "uint16_t" ,the "p_value" field must point to a data
 *                      with type of "uint16_t".
 *
 * @param[in]   param_type   Blood pressure service parameter type: @ref T_BLS_PARAM_TYPE
 * @param[in]   length       Length of data to write
 * @param[in]   p_value      Pointer to data to write.
 *                           This is dependent on the parameter type and will be cast to the appropriate data type.
                             If param_type is set to @ref BLS_PARAM_BLOOD_PRESUREE_FEATURE, p_value pointer to the current
                             blood pressure feature. Type is org.bluetooth.characteristic.blood_pressure_feature.
 *
 * @return Operation result.
 * @retval true Operation success.
 * @retval false Operation failure.
 *
 * <b>Example usage</b>
 * \code{.c}
    void test(void)
    {
        uint16_t blood_pressure_feature = BLS_FEATURE_BODY_MOVEMENT_DETECTION_SUPPORT_BIT |
                                          BLS_FEATURE_CUFF_FIT_DETECTION_SUPPORT_BIT;
        bls_set_parameter(BLS_PARAM_BLOOD_PRESUREE_FEATURE, 2, &blood_pressure_feature);
    }
 * \endcode
 */
bool bls_set_parameter(T_BLS_PARAM_TYPE param_type, uint8_t length, void *p_value);


/**
 * @brief       Send blood pressure measurement value indication data .
 *
 *
 * @param[in]   conn_id        Connection id.
 * @param[in]   service_id     Service id.
 * @param[in]   p_value        Pointer to data to indicate.
                               Type is org.bluetooth.characteristic.blood_pressure_measurement.
 * @return Operation result.
 * @retval true Operation success.
 * @retval false Operation failure.
 *
 * <b>Example usage</b>
 * \code{.c}
    void test(void)
    {
        uint8_t conn_id = 0;
        T_BLOOD_PRESSURE_MEASURMENT bls_meas_value = {0};
        SFLOAT bls_measure_pulse_rate = {0x30, 0x00};

        bls_meas_value.bp_meas_flag = (BLS_FLAG_MEASUREMENT_UINT_BIT |
                                       BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT |
                                       BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT |
                                       BLS_FLAG_MEASUREMENT_USER_ID_BIT |
                                       BLS_FLAG_MEASUREMENT_STATUS_BIT);
        bls_meas_value.time_stamp = (T_BLS_TIME_STAMP) {2017, 9, 20, 20, 6, 8};
        memcpy(&bls_meas_value.bp_meas_pulse_rate, &bls_measure_pulse_rate, 2);
        bls_meas_value.bp_meas_user_id = 0;
        bls_meas_value.bp_meas_status = (T_BLOOD_PRESSUREE_MEAS_STATUS) {0};

        bls_blood_pressure_measurement_value_indicate(conn_id, bls_id, blp_meas_value);
    }
 * \endcode
 */
bool bls_blood_pressure_measurement_value_indicate(uint8_t conn_id, T_SERVER_ID service_id,
                                                   T_BLOOD_PRESSURE_MEASURMENT *p_data);


#if BLS_INTERMEDIATE_CUFF_PRESSURE_SUPPORT
/**
 * @brief       Send intermediate cuff pressure value notification data .
 *
 *
 * @param[in]   conn_id        Connection id.
 * @param[in]   service_id     Service id.
 * @param[in]   blood pressure_level  The current charge level of a blood pressure.
                               Type is org.bluetooth.characteristic.blood_pressure_measurement.
 * @return Operation result.
 * @retval true Operation success.
 * @retval false Operation failure.
 *
 * <b>Example usage</b>
 * \code{.c}
    void test(void)
    {
         T_BLOOD_PRESSURE_MEASURMENT bls_meas_value = {0};
        SFLOAT bls_measure_pulse_rate = {0x30, 0x00};

        bls_meas_value.bp_meas_flag = (BLS_FLAG_MEASUREMENT_UINT_BIT |
                                       BLS_FLAG_MEASUREMENT_TIMESTAMP_PRESENT_BIT |
                                       BLS_FLAG_MEASUREMENT_PULSE_RATE_BIT |
                                       BLS_FLAG_MEASUREMENT_USER_ID_BIT |
                                       BLS_FLAG_MEASUREMENT_STATUS_BIT);
        bls_meas_value.time_stamp = (T_BLS_TIME_STAMP) {2017, 9, 20, 20, 6, 8};
        memcpy(&bls_meas_value.bp_meas_pulse_rate, &bls_measure_pulse_rate, 2);
        bls_meas_value.bp_meas_user_id = 0;
        bls_meas_value.bp_meas_status = (T_BLOOD_PRESSUREE_MEAS_STATUS) {0};

        bls_intermediate_cuff_pressure_value_notify(conn_id, bls_id, blp_meas_value);
    }
 * \endcode
 */
bool bls_intermediate_cuff_pressure_value_notify(uint8_t conn_id, T_SERVER_ID service_id,
                                                 T_BLOOD_PRESSURE_MEASURMENT *p_data);
#endif

/** @} End of BLS_Exported_Functions */

/** @} End of BLS */


#ifdef  __cplusplus
}
#endif      /*  __cplusplus */

#endif  /* _BLS_H_ */
